package gspringboot

import "gitee.com/hongzhaomin/gspring/iface"

// ApplicationRunListener 应用启动监听器接口
type ApplicationRunListener interface {

	// Starting 在容器创建之前调用
	Starting(environment ConfigurationEnvironment, logger iface.GspringLogger)

	// ContextPrepared 在容器创建完且准备工作完成之后调用
	ContextPrepared(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger)

	// Stared 在容器启动完成之后，runners执行之前调用
	Stared(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger)

	// Ready runners执行之后调用
	Ready(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger)
}

func NewApplicationRunListeners(listeners ...ApplicationRunListener) *ApplicationRunListeners {
	return &ApplicationRunListeners{
		listeners: listeners,
	}
}

var _ ApplicationRunListener = (*ApplicationRunListeners)(nil)

type ApplicationRunListeners struct {
	listeners []ApplicationRunListener
}

func (my *ApplicationRunListeners) AddListeners(listeners ...ApplicationRunListener) {
	my.listeners = append(my.listeners, listeners...)
}

func (my *ApplicationRunListeners) Starting(environment ConfigurationEnvironment, logger iface.GspringLogger) {
	my.doWithListener(func(listener ApplicationRunListener) {
		listener.Starting(environment, logger)
	})
}

func (my *ApplicationRunListeners) ContextPrepared(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger) {
	my.doWithListener(func(listener ApplicationRunListener) {
		listener.ContextPrepared(context, environment, logger)
	})
}

func (my *ApplicationRunListeners) Stared(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger) {
	my.doWithListener(func(listener ApplicationRunListener) {
		listener.Stared(context, environment, logger)
	})
}

func (my *ApplicationRunListeners) Ready(context iface.ApplicationContext, environment ConfigurationEnvironment, logger iface.GspringLogger) {
	my.doWithListener(func(listener ApplicationRunListener) {
		listener.Ready(context, environment, logger)
	})
}

func (my *ApplicationRunListeners) doWithListener(doInvoke func(listener ApplicationRunListener)) {
	for _, listener := range my.listeners {
		doInvoke(listener)
	}
}
